package q7_gc_test;

import java.util.concurrent.TimeUnit;

/*
JVM的参数类型：
    1、标配参数
        -version
        -help
        java -showversion
    2、X参数（了解）
        -Xint   解释执行
        -Xcomp  第一次使用就编译成本地代码
        -Xmixed 混合模式
    3、XX参数
        Boolean类型
            公式
                -XX:+或者-某个属性值
                +表示开启
                -表示关闭
            Case
                是否打印GC收集细节
                    -XX:-PrintGCDetails
                    -XX:+PrintGCDetails
                是否使用串行垃圾回收器
                    -XX:-UseSerialGC
                    -XX:+UseSerialGC
                是否使用并行垃圾回收器
                    -XX:-UseParallelGC
                    -XX:+UseParallelGC
        KV设值类型
            公式：-XX:属性key=属性值value
            Case:
                -XX:MetaspaceSize=128m
                -XX:MaxTenuringThreshold=15
        jinfo举例，如何查看当前运行程序的配置
            如何查看一个正在运行中的java程序，它的某个jvm参数是否开启，具体值是多少？
            jinfo -flag PrintGCDetails 5516
            jinfo -flag MetaspaceSize 5516
            jinfo -flags 5516   查看所有参数
        题外话（坑题）
            两个经典参数：-Xms和-Xmx
            这个你如何解释
                -Xms等价于-XX:InitialHeapSize
                -Xmx等价于-XX:MaxHeapSize

盘点家底查看JVM默认值
    -XX:+PrintFlagsInitial
        主要查看初始默认
        公式：
            java -XX:+PrintFlagsInitial -version
            java -XX:+PrintFlagsInitial
    -XX:+PrintFlagsFinal
        主要查看修改更新
        公式：
            java -XX:+PrintFlagsFinal -version
            java -XX:+PrintFlagsFinal
            := 为修改过值
    PrintFlagsFinal举例，运行java命令的同时打印出参数
        java -XX:+PrintFlagsFinal -XX:MetaspaceSize=128m 程序名
    -XX:+PrintCommandLineFlags
        java -XX:+PrintCommandLineFlags -version

你平时工作用过的JVM常用基本配置参数有哪些？
    -Xms
        初始大小内存，默认为物理内存1/64
        等价于-XX:InitialHeapSize
    -Xmx
        最大分配内存，默认为物理内存1/4
        等价于-XX:MaxHeapSize
    -Xss
        设置单个线程栈的大小，一般默认为512K~1024K
        等价于-XX:ThreadStackSize
    -Xmn
        设置年经代大小
    -XX:MetaspaceSize
        设置元空间大小
            元空间的本质和永久代类似，都是对JVM规范中方法区的实现。
            不过元空间与永久代之间最大的区别在于：
                元空间并不在虚拟机中，而是使用本地内存。
                因此，默认情况下，元空间的大小仅受本地内存限制
        -Xms10m -Xmx10m -XX:MetaspaceSize=1024m -XX:+PrintFlagsFinal
    典型设置案例
        -Xms128m -Xmx4096m -Xss1024k -XX:MetaspaceSize=512m -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseSerialGC
    -XX:+PrintGCDetails
        输出详细GC收集日志信息
        -Xms10m -Xmx10m -XX:+PrintGCDetails
        GC
            [GC [PSYoungGen: 1932K->504K(2560K)] 1932K->688K(9728K), 0.0090622 secs] [Times: user=0.05 sys=0.00, real=0.01 secs]
            GC类型
            YoungGC前新生代内存占用、YoungGC后新生代内存占用、新生代总共大小
            YoungGC前JVM堆内存占用、YoungGC后JVM堆内存使用、JVM堆总大小
            YoungGC耗时
            YoungGC用户耗时、YoungGC系统耗时、YoungGC实际耗时
        FullGC
            [Full GC [PSYoungGen: 488K->0K(2560K)] [ParOldGen: 228K->656K(7168K)] 716K->656K(9728K), [Metaspace: 3440K->3440K(1056768K)], 0.0059552 secs] [Times: user=0.05 sys=0.00, real=0.01 secs]
            jdk1.8前：GC类型
                     Young区、GC前Young区内存占用、GC后Young区内存占用、Young区总大小
                     Old区、GC前Old区内存占用、GC后Old区内存占用、Old区总大小
                     GC前堆内存占用、GC后堆内存占用、JVM堆总大小
                     Perm区、GC前Perm区内存占用、GC后Perm区内存占用、Perm区总大小、GC耗时
                     GC用户耗时、GC系统耗时、GC实际耗时
            jdk1.8后：GC类型
                     Young区、GC前Young区内存占用、GC后Young区内存占用、Young区总大小
                     Old区、GC前Old区内存占用、GC后Old区内存占用、Old区总大小
                     GC前堆内存占用、GC后堆内存占用、JVM堆总大小
                     Metaspace区、GC前Metaspace区内存占用、GC后Metaspace区内存占用、Metaspace区总大小、GC耗时
                     GC用户耗时、GC系统耗时、GC实际耗时
    -XX:SurvivorRatio
        设置新生代中eden和S0/S1空间的比例
        默认：-XX:SurvivorRatio=8, Eden:S0:S1=8:1:1
        假如：-XX:SurvivorRatio=4, Eden:S0:S1=4:1:1
        SurvivorRatio值就是设置eden区的比例占多少，S0/S1相同
        示例：-XX:+PrintGCDetails -XX:+UseSerialGC -Xms10m -Xmx10m -XX:SurvivorRatio=4
    -XX:NewRatio
        配置年经代与老年代在堆结构的占比
        默认：-XX:NewRatio=2 新生代占1，老年代占2，年经代占整个堆的1/3
        假如：-XX:NewRatio=4 新生代占1，老年代占4，年经代占整个堆的1/5
        NewRatio值就是设置老年代的占比，剩下的1给新生代
        示例：-XX:+PrintGCDetails -XX:+UseSerialGC -Xms10m -Xmx10m -XX:NewRatio=4
    -XX:MaxTenuringThreshold
        查看默认进入老年代年龄（jdk8不能超过0~15范围）：
            jinfo -flag MaxTenuringThreshold 17344
        -XX:MaxTenuringThreshold=0: 设置垃圾最大年龄。如果设置为0的话，则年轻对象不经过Survivor区，直接进入老年代。对老年代比较多的应用，可以提高效率。
        如果将此值设置为一个较大值，则年轻代对象会在Survivor区进行多次复制，这样可以增加对象在年轻代的存活时间，增加在年轻代即被回收的概率。
        示例：-XX:MaxTenuringThreshold=12
*/
public class JVMParamsDemo {

    public static void main(String[] args) {
        System.out.println("GC DEMO");

        byte[] bytes = new byte[50*1024*1024];
//        try {
//            TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
    }
}
